package com.cro.prison.service.impl;/**
 * @author augus
 * @create 2022-11-07-16:08
 */

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cro.prison.dao.DepartDao;
import com.cro.prison.dao.DeviceDao;
import com.cro.prison.dao.ErrorMessageDao;
import com.cro.prison.entity.pojo.Depart;
import com.cro.prison.entity.pojo.Device;
import com.cro.prison.entity.pojo.ErrorMessage;
import com.cro.prison.entity.vo.Category2Vo;
import com.cro.prison.service.DepartService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @ClassName:DepartServiceImpl
 * @Description:TODO
 * @author Augus
 * @date 2022/11/7 16:08
 * @Version 1.0
 **/

@Service("departService")
public class DepartServiceImpl extends ServiceImpl<DepartDao, Depart> implements DepartService {

    @Autowired
    ErrorMessageDao errorMessageDao;
    @Autowired
    DeviceDao deviceDao;
    @Autowired
    ThreadPoolExecutor executor;
    @Override
    public Map<Long, List<Category2Vo>> getCatalogJson() throws ExecutionException, InterruptedException {
        HashMap<Long, List<Depart>> departMap = new HashMap<>();
        CompletableFuture<HashMap<Long, List<Depart>>> departMapFuture = CompletableFuture.supplyAsync(()->{
            List<Depart> selectList = baseMapper.selectList(null);
            for (Depart depart : selectList) {
                List<Depart> departs = departMap.getOrDefault(depart.getPid(), new ArrayList<>());
                departs.add(depart);
                departMap.put(depart.getPid(),departs);
            }
            return departMap;
        },executor);
        //存储按照pid Depart
        HashMap<Long, List<Device>> deviceMap = new HashMap<>();
        //存储按照depart 存储device
        CompletableFuture<HashMap<Long, List<Device>>> deviceMapFuture = CompletableFuture.supplyAsync(()->{
            List<Device> deviceList = deviceDao.selectList(new QueryWrapper<>());
            for (Device device : deviceList) {
                List<Device> devices = deviceMap.getOrDefault(device.getDepartId(), new ArrayList<>());
                devices.add(device);
                deviceMap.put(device.getDepartId(),devices);
            }
            return deviceMap;
        },executor);
        HashMap<Long, List<ErrorMessage>> errorMessageMap = new HashMap<>();
        CompletableFuture<HashMap<Long,List<ErrorMessage>>> errorMessageFuture = CompletableFuture.supplyAsync(()->{
            List<ErrorMessage> errorMessageList = errorMessageDao.selectList(new QueryWrapper<>());
            for (ErrorMessage errorMessage : errorMessageList) {
                List<ErrorMessage> errorMessages = errorMessageMap.getOrDefault(errorMessage.getDeviceId(), new ArrayList<>());
                errorMessages.add(errorMessage);
                errorMessageMap.put(errorMessage.getDeviceId(),errorMessages);
            }
            return errorMessageMap;
        },executor);
        CompletableFuture<Void> allOf = CompletableFuture.allOf(departMapFuture, deviceMapFuture, errorMessageFuture);
        allOf.get();
        List<Depart> level1Categories = departMap.get(0L);
        //2、封装数据
        Map<Long, List<Category2Vo>> categoryJson = level1Categories.stream().collect(Collectors.toMap(k -> k.getId(), l1 -> {
            //1、每一个当前级分类，查到这个分类的子分类
            List<Depart> level2Categories =  departMap.get(l1.getId());
            //2、封装上面的结果
            List<Category2Vo> category2Vos = null;
            if (level2Categories != null) {
                category2Vos = level2Categories.stream().map(l2 -> {
                    Category2Vo category2Vo = new Category2Vo(l2.getPid(), l2.getId(), l2.getName(), null);
                    List<Depart> level3Categories =    departMap.get(l2.getId());
                    List<Category2Vo.Category3Vo> category3Vos = null;
                    if(level3Categories != null){
                        category3Vos = level3Categories.stream().map(l3 -> {
                            Category2Vo.Category3Vo category3Vo = new Category2Vo.Category3Vo(l3.getPid(), l3.getId(), l3.getName(), null);
                                List<Device> level4Categories = deviceMap.get(l3.getId());
                                List<Category2Vo.Category3Vo.Category4Vo> category4Vos = null;
                                if(level4Categories!=null){
                                    category4Vos = level4Categories.stream().map(l4 -> {
                                        Category2Vo.Category3Vo.Category4Vo category4Vo = new Category2Vo.Category3Vo.Category4Vo(l4.getDepartId(),l4.getId(),l4.getName(),l4.getSrc(),null);
                                        List<ErrorMessage> level5Categories = errorMessageMap.get(l4.getId());
                                        List<Category2Vo.Category3Vo.Category4Vo.Category5Vo> category5Vos = null;
                                        if(level5Categories != null){
                                            category5Vos = level5Categories.stream().map(l5 -> {
                                                SimpleDateFormat format = new SimpleDateFormat("yyMMdd");
                                                String time = format.format(l5.getCreateTime());
                                                Category2Vo.Category3Vo.Category4Vo.Category5Vo category5Vo = new Category2Vo.Category3Vo.Category4Vo.Category5Vo(l5.getDeviceId(), l5.getId(), "异常" + time + "-" + l5.getId(), l5.getVideoSrc());
                                                return category5Vo;
                                            }).collect(Collectors.toList());
                                            category4Vo.setChildren(category5Vos);
                                        }
                                        return category4Vo;
                                    }).collect(Collectors.toList());
                                    category3Vo.setChildren(category4Vos);
                                }
                                return category3Vo;
                        }).collect(Collectors.toList());
                        category2Vo.setChildren(category3Vos);
                    }
                    return category2Vo;
                }).collect(Collectors.toList());
            }
            return category2Vos;
        }));
        return categoryJson;
    }

}
